//
// Created by JYL on 2025/1/23.
//
/**
 ****************************************************************************************************
 * @file        iap.c
 * @author      935848559@qq.com
 * @version     V1.0
 * @date        2024-03-11
 * @brief       IAP 代码
 * @license     Copyright (c) 2020-2032,
 ****************************************************************************************************
 * @attention
 *
 *
 ****************************************************************************************************
 */


#include "iap.h"
#include "stdio.h"
iapfun jump2app;

/**
 * @brief       IAP 版本提示
 * @param       void
 * @retval      无
 */
void IAP_printf(void)
{
    printf("\r\n");
    printf("******************************************************\r\n");
    printf("*                                                    *\r\n");
    printf("*                IAP     Version: 0.0.2              *\r\n");
    printf("*                                                    *\r\n");
    printf("******************************************************\r\n");
}

/**
 * @brief       IAP写入APP BIN
 * @param       appxaddr : 应用程序的起始地址
 * @param       appbuf   : 应用程序CODE
 * @param       appsize  : 应用程序大小(字节)
 * @retval      无
 */
void iap_write_appbin(uint32_t appxaddr, uint8_t *appbuf, uint32_t appsize)
{
    if(Write_Flash(appxaddr,appbuf,appsize) != FLASH_OK)
        printf("iap_write_appbin error!!\r\n");
    else
        printf("iap_write_appbin ok!!\r\n");

}

/**
 * @brief       设置栈顶地址
 * @note        左侧的红X, 属于MDK误报, 实际是没问题的
 * @param       addr: 栈顶地址
 * @retval      无
 */
void sys_msr_msp(uint32_t addr)
{
    __set_MSP(addr);            /* 设置栈顶地址 */
}

iapfun JumpToApplication;

/**
 * @brief       跳转到应用程序段(执行APP)
 * @param       appxaddr : 应用程序的起始地址

 * @retval      无
 */
void iap_load_app(uint32_t appxaddr)
{

    if (((*(volatile  uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000)     /* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
    {
        /* 用户代码区第二个字为程序开始地址(复位地址) */
        jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);
        printf("jump2app = %p\r\n",jump2app);   //打印main地址，我的测试程序显示地址是0x080050d1
        /* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */
        sys_msr_msp(*(volatile uint32_t *)appxaddr);
        printf("appxaddr = %x\r\n",appxaddr);   //打印栈顶地址，应该是0x08005000

        /* 跳转到APP */
        jump2app();
    }
    else
    {
        printf("program in flash is error\r\n");
    }
}

